/*
 * @Author: Tyler
 * @Date: 2025-10-20 21:25:05
 * @Description: 
 * Copyright (c) 2025 by User/Corp, All Rights Reserved.
 */
#pragma once

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// #include <Python.h>
#include <nlohmann/json.hpp>

using namespace std;
using json = nlohmann::json;

inline void readJson(const string& configFile, json& config) {
    // 打开 JSON 文件
    ifstream file(configFile);
    if (!file.is_open()) {
        cerr << "Failed to open file." << endl;
    }

    // 解析 JSON 文件
    try {
        stringstream buffer;
        buffer << file.rdbuf();
        config = json::parse(buffer.str());
    } catch (json::parse_error& e) {
        cerr << "JSON parse error: " << e.what() << endl;
        if (file.is_open()) {
            file.close();
        }
    }

    if (file.is_open()) {
        file.close();
    }
}
inline void visitModel(const json& config) {
    // 访问模型信息
    string model_name = config["model"]["name"];
    vector<int> input_shape = config["model"]["input_shape"];

    cout << "Model Name: " << model_name << endl;
    cout << "Input Shape: ";
    for (int dim : input_shape) {
        cout << dim << " ";
    }
    cout << endl;
}
inline void visitLayers(const json& config) {
    // 访问层信息
    cout << "Layers:" << endl;
    for (const auto& layer : config["model"]["layers"]) {
        string type = layer["type"];
        cout << "  Type: " << type << endl;

        if (type == "Conv2D") {
            int filters = layer["filters"];
            vector<int> kernel_size = layer["kernel_size"];
            string activation = layer["activation"];
            string padding = layer["padding"];

            cout << "    Filters: " << filters << endl;
            cout << "    Kernel Size: ";
            for (int size : kernel_size) {
                cout << size << " ";
            }
            cout << endl;
            cout << "    Activation: " << activation << endl;
            cout << "    Padding: " << padding << endl;
        } else if (type == "MaxPooling2D") {
            vector<int> pool_size = layer["pool_size"];

            cout << "    Pool Size: ";
            for (int size : pool_size) {
                cout << size << " ";
            }
            cout << endl;
        } else if (type == "Flatten") {
            // No additional parameters for Flatten layer
        } else if (type == "Dense") {
            int units = layer["units"];
            string activation = layer["activation"];

            cout << "    Units: " << units << endl;
            cout << "    Activation: " << activation << endl;
        }
    }
}
inline void visitTraining(const json& config) {
    // 访问训练信息
    string optimizer = config["training"]["optimizer"];
    string loss_function = config["training"]["loss_function"];
    vector<string> metrics = config["training"]["metrics"];
    int epochs = config["training"]["epochs"];
    int batch_size = config["training"]["batch_size"];

    cout << "\nTraining Information:" << endl;
    cout << "  Optimizer: " << optimizer << endl;
    cout << "  Loss Function: " << loss_function << endl;
    cout << "  Metrics: ";
    for (const auto& metric : metrics) {
        cout << metric << " ";
    }
    cout << endl;
    cout << "  Epochs: " << epochs << endl;
    cout << "  Batch Size: " << batch_size << endl;
}
inline void visitData(const json& config) {
    // 访问数据信息
    string dataset = config["data"]["dataset"];
    double train_split = config["data"]["train_split"];
    double validation_split = config["data"]["validation_split"];
    double test_split = config["data"]["test_split"];
    bool normalize = config["data"]["preprocessing"]["normalize"];
    double rescale_factor = config["data"]["preprocessing"]["rescale_factor"];

    cout << "\nData Information:" << endl;
    cout << "  Dataset: " << dataset << endl;
    cout << "  Train Split: " << train_split << endl;
    cout << "  Validation Split: " << validation_split << endl;
    cout << "  Test Split: " << test_split << endl;
    cout << "  Preprocessing:" << endl;
    cout << "    Normalize: " << (normalize ? "true" : "false") << endl;
    cout << "    Rescale Factor: " << rescale_factor << endl;
}